export interface IScreepsResponseData {
    ok?: number
    error?: string
    [key: string]: unknown
}

export interface IBaseResponse {
    ok: number
    error: string
}

export interface ISignin extends IBaseResponse {
    token: string
}

export interface IPvp extends IBaseResponse {
    pvp: {
        [shard in Shard]: {
            time: number
            rooms: { _id: string; lastPvpTime: number }[]
        }
    }
}

export type Shard = 'shard0' | 'shard1' | 'shard2' | 'shard3'

export interface INuke extends IBaseResponse {
    nukes: {
        [shard in Shard]: {
            room: string
            x: number
            y: number
            landTime: number
            launchRoomName: string
        }[]
    }
}

export interface IUser extends IBaseResponse {
    user: {
        _id: string
        steam: { id: string }
        username: string
        badge: {
            type: string
            color1: string
            color2: string
            color3: string
            param: number
            flip: boolean
        }
        gcl: number
        power: number
    }
}

export interface IRoomAreaInfo extends IBaseResponse {
    room: {
        _id: string
        status: string
        respawnArea: number
        novice: number
    }
}

export interface IOrder {
    _id: string
    type: 'buy' | 'sell'
    amount: number
    remainingAmount: number
    price: number
    roomName?: string
}

export interface IMarketOrder extends IBaseResponse {
    list: IOrder[]
}

export interface IUserRank extends IBaseResponse {
    list: {
        _id: string
        user: string
        season: string
        score: number
        rank: number
    }[]
}

export interface IRoomObjects extends IBaseResponse {
    objects: IGameObject[]
    users: {
        [id: string]: {
            _id: number
            username: string
            badge?: {
                type: string
                color1: string
                color2: string
                color3: string
                param: number
                flip: boolean
            }
        }
    }
}

export interface IGameObject {
    _id: string
    type: string
    x: number
    y: number
    room: string
}

export interface Source extends IGameObject {
    type: 'source'
    energy: number
    energyCapacity: number
    ticksToRegeneration: number
    invaderHarvested: number
    nextRegenerationTime: number
}

export interface Mineral extends IGameObject {
    type: 'mineral'
    mineralType: string
    mineralAmount: number
    nextRegenerationTime: number
}

export interface ConstructedWall extends IGameObject {
    type: 'constructedWall'
    hits: number
    hitsMax: number
    notifyWhenAttacked: boolean
}

export interface Road extends IGameObject {
    type: 'road'
    hits: number
    hitsMax: number
    notifyWhenAttacked: boolean
    nextDecayTime: number
}

export interface Controller extends IGameObject {
    type: 'controller'
    level: number
    progress: number
    progressTotal: number
    user: string
    downgradeTime: number
    safeMode: number
    safeModeAvailable: number
    safeModeCooldown: number
    upgradeBlocked: number
    downgradeBlocked: number
    reservation?: unknown
    sign?: {
        user: string
        time: number
        text: string
        datetime: number
    }
    isPowerEnabled: boolean
    effects: unknown
}

export interface Spawn extends IGameObject {
    type: 'spawn'
    name: string
    hits: number
    hitsMax: number
    notifyWhenAttacked: boolean
    spawning?: unknown
    off: boolean
    store: {
        energy: number
    }
    storeCapacityResource: {
        energy: number
    }
}

export interface Extension extends IGameObject {
    type: 'extension'
    hits: number
    hitsMax: number
    user: string
    notifyWhenAttacked: boolean
    store: {
        energy: number
    }
    storeCapacityResource: {
        energy: number
    }
    off: boolean
}

export interface Storage extends IGameObject {
    type: 'storage'
    hits: number
    hitsMax: number
    notifyWhenAttacked: boolean
    user: string
    store: {
        [type: string]: number
    }
    storeCapacity: number
    effects: {
        [type: string]: {
            effect: number
            power: number
            level: number
            endTime: number
        }
    }
}

export interface Tower extends IGameObject {
    type: 'tower'
    hits: number
    hitsMax: number
    notifyWhenAttacked: boolean
    user: string
    store: {
        energy: number
    }
    storeCapacityResource: {
        energy: number
    }
    actionLog: {
        attack?: unknown
        heal?: unknown
        repair?: unknown
    }
}

export interface Rampart extends IGameObject {
    type: 'rampart'
    hits: number
    hitsMax: number
    user: string
    notifyWhenAttacked: boolean
    nextDecayTime: number
}

export interface Extractor extends IGameObject {
    type: 'extractor'
    hits: number
    hitsMax: number
    user: string
    notifyWhenAttacked: boolean
    cooldown: number
}

export interface Terminal extends IGameObject {
    type: 'terminal'
    hits: number
    hitsMax: number
    user: string
    notifyWhenAttacked: boolean
    store: {
        [type: string]: number
    }
    storeCapacity: number
    cooldownTime: number
    send?: unknown
}

export interface Observer extends IGameObject {
    type: 'observer'
    hits: number
    hitsMax: number
    user: string
    notifyWhenAttacked: boolean
    observeRoom?: unknown
}

export interface PowerSpawn extends IGameObject {
    type: 'powerSpawn'
    hits: number
    hitsMax: number
    user: string
    notifyWhenAttacked: boolean
    store: {
        energy: number
        power: number
    }
    storeCapacityResource: {
        energy: number
        power: number
    }
}

export interface Nuker extends IGameObject {
    type: 'nuker'
    hits: number
    hitsMax: number
    user: string
    notifyWhenAttacked: boolean
    store: {
        energy: number
        G: number
    }
    storeCapacityResource: {
        energy: number
        G: number
    }
    cooldownTime: number
}

export interface Factory extends IGameObject {
    type: 'factory'
    hits: number
    hitsMax: number
    user: string
    notifyWhenAttacked: boolean
    store: {
        [type: string]: number
    }
    storeCapacity: number
    cooldown: number
    cooldownTime: number
    effects: {
        [type: string]: {
            effect: number
            power: number
            level: number
            endTime: number
        }
    }
    level: number
}
